/**
 * File: GatherStatisticFasta.java
 * Created by: mhaimel
 * Created on: 30 Jun 2009
 * CVS:  $Id: GatherStatisticFasta.java,v 1.1 2009/11/24 16:24:00 mhaimel Exp $
 */
package uk.ac.ebi.curtain.exec;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

import uk.ac.ebi.curtain.utils.CurtainUncheckedException;
import uk.ac.ebi.curtain.utils.data.FileType;
import uk.ac.ebi.curtain.utils.data.ReadType;
import uk.ac.ebi.curtain.utils.file.EntryMapper;
import uk.ac.ebi.curtain.utils.file.EntryMapperBean;
import uk.ac.ebi.curtain.utils.file.FileInfo;
import uk.ac.ebi.curtain.utils.file.ParseUtil;
import uk.ac.ebi.curtain.utils.io.impl.FileIO;
import uk.ac.ebi.velvet.processor.StatisticsInfo;
import uk.ac.ebi.velvet.processor.StatisticsProcessor;
import uk.ac.ebi.velvet.processor.impl.SequenceStatisticsProcessor;

/**
 * @author mhaimel
 * 
 */
public class GatherStatisticFasta {

	public static void main(String[] args) {
		final AtomicInteger limit = new AtomicInteger(100);
		PrintStream out = System.out;
		int i = 0;
		try{
			while (i < args.length && args[i].startsWith("-")) {
				if (args[i].equals("-h") || args[i].equals("-help")
						|| args[i].equals("--help")) {
					System.out.println("-l\tSequence cutoff length, default:100");
					System.out.println("-o\tOutput file, default:stdout");
					++i;
					System.exit(1);
				} else if (args[i].equals("-l")) {
					++i;
					limit.set(Integer.valueOf(args[i++]));
				} else if (args[i].equals("-o")) {
					out = new PrintStream(new File(args[++i]));
					++i;
				}
			}
			while(i < args.length){
				String in = args[i++];
				FileInfo fi = new FileInfo(in, FileType.fasta, ReadType.ShortPaired);
				final MyProcessor statProc = new MyProcessor(fi);
				final AtomicLong cnt = new AtomicLong(0);
				final AtomicInteger plainCnt = new AtomicInteger(0);
				final AtomicLong plainSum = new AtomicLong(0);
				ParseUtil seqParser = fi.getFileType().getParser();
				seqParser.parse(fi, new EntryMapper() {
					@Override
					public void mapEntry(EntryMapperBean bean) {
	
						int seqLen = bean.getSequenceLength();
						if (seqLen >= limit.get()) {
							statProc.addEntry(bean);
							String seq = bean.getSequence();
							long len = seq.length();
							long len2 = seq.replace("N", "").length();
							long delta = (long) len - len2;
							if (delta == 0) {
								plainCnt.incrementAndGet();
								plainSum.addAndGet(len);
							}
							cnt.addAndGet(delta);
						}
					}
				});
				StatisticsInfo stats = statProc.processStatistics();
				Integer n50 = stats.getN50();

				Integer cntN50 = 0;				
				for(Entry<Integer,List<Integer>> entry : statProc.getSP().getCoverage2ScoreMap().entrySet()){
					for(Integer len : entry.getValue()){
						if(len >= n50){
							++cntN50;
						}
					}
				}
				stats.setCutoffCov(null);
				stats.setExpCov(null);
				System.out.println(stats.toUserString() + "\tPlain=" + plainCnt
						+ "\tNs=" + cnt + "\tPlainsum=" + plainSum + "\tN > N50: "
						+ cntN50 + ";\t" + fi.getFile());
			}
		} catch (FileNotFoundException e) {
			throw new CurtainUncheckedException("Not able to write results to " + args[i]);
		} finally{
			FileIO.closeQuietly(out);
		}
	}

	public static class MyProcessor extends SequenceStatisticsProcessor {

		public MyProcessor(FileInfo statsFile) {
			super(statsFile);
		}

		public StatisticsProcessor getSP() {
			return getStatsProc();
		}

		@Override
		protected StatisticsProcessor getStatsProc() {
			return super.getStatsProc();
		}

	}

}
